home *** CD-ROM | disk | FTP | other *** search
/ PC Open 101 / PC Open 101 CD 1.bin / CD1 / INTERNET / EMAIL / pop file / setup.exe / POPFile / Logger.pm < prev    next >
Encoding:
Perl POD Document  |  2004-09-21  |  7.6 KB  |  307 lines

  1. # POPFILE LOADABLE MODULE
  2. package POPFile::Logger;
  3.  
  4. use POPFile::Module;
  5. @ISA = ("POPFile::Module");
  6.  
  7. #----------------------------------------------------------------------------
  8. #
  9. # This module handles POPFile's logger.  It is used to save debugging
  10. # information to disk or to send it to the screen.
  11. #
  12. # Copyright (c) 2001-2004 John Graham-Cumming
  13. #
  14. #   This file is part of POPFile
  15. #
  16. #   POPFile is free software; you can redistribute it and/or modify
  17. #   it under the terms of the GNU General Public License as published by
  18. #   the Free Software Foundation; either version 2 of the License, or
  19. #   (at your option) any later version.
  20. #
  21. #   POPFile is distributed in the hope that it will be useful,
  22. #   but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24. #   GNU General Public License for more details.
  25. #
  26. #   You should have received a copy of the GNU General Public License
  27. #   along with POPFile; if not, write to the Free Software
  28. #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  29. #
  30. #----------------------------------------------------------------------------
  31.  
  32. use strict;
  33. use warnings;
  34. use locale;
  35.  
  36. # Constant used by the log rotation code
  37. my $seconds_per_day = 60 * 60 * 24;
  38.  
  39. #----------------------------------------------------------------------------
  40. # new
  41. #
  42. #   Class new() function
  43. #----------------------------------------------------------------------------
  44. sub new
  45. {
  46.     my $proto = shift;
  47.     my $class = ref($proto) || $proto;
  48.     my $self = POPFile::Module->new();
  49.  
  50.     # The name of the debug file
  51.  
  52.     $self->{debug_filename__} = '';
  53.  
  54.     # The last ten lines sent to the logger
  55.  
  56.     $self->{last_ten__} = ();
  57.  
  58.     $self->{initialize_called__} = 0;
  59.  
  60.     bless($self, $class);
  61.  
  62.     $self->name( 'logger' );
  63.  
  64.     return $self;
  65. }
  66.  
  67. #----------------------------------------------------------------------------
  68. #
  69. # initialize
  70. #
  71. # Called to initialize the interface
  72. #
  73. # ---------------------------------------------------------------------------
  74. sub initialize
  75. {
  76.     my ( $self ) = @_;
  77.  
  78.     $self->{initialize_called__} = 1;
  79.  
  80.     # Start with debugging to file
  81.  
  82.     $self->global_config_( 'debug', 1 );
  83.  
  84.     # The default location for log files
  85.  
  86.     $self->config_( 'logdir', './' );
  87.  
  88.     # The output format for log files, can be default, tabbed or csv
  89.  
  90.     $self->config_( 'format', 'default' );
  91.  
  92.     # The log level.  There are three levels of log:
  93.     #
  94.     # 0   Critical log messages
  95.     # 1   Verbose logging
  96.     # 2   Maximum verbosity
  97.  
  98.     $self->config_( 'level', 0 );
  99.  
  100.     $self->{last_tickd__} = time;
  101.  
  102.     $self->mq_register_( 'TICKD', $self );
  103.  
  104.     return 1;
  105. }
  106.  
  107. # ---------------------------------------------------------------------------
  108. #
  109. # deliver
  110. #
  111. # Called by the message queue to deliver a message
  112. #
  113. # There is no return value from this method
  114. #
  115. # ---------------------------------------------------------------------------
  116. sub deliver
  117. {
  118.     my ( $self, $type, @message ) = @_;
  119.  
  120.     # If a day has passed then clean up log files
  121.  
  122.     if ( $type eq 'TICKD' ) {
  123.         $self->remove_debug_files();
  124.     }
  125. }
  126.  
  127. #----------------------------------------------------------------------------
  128. #
  129. # start
  130. #
  131. # Called to start the logger running
  132. #
  133. #----------------------------------------------------------------------------
  134. sub start
  135. {
  136.     my ( $self ) = @_;
  137.  
  138.     $self->calculate_today__();
  139.  
  140.     return 1;
  141. }
  142.  
  143. # ---------------------------------------------------------------------------
  144. #
  145. # service
  146. #
  147. # ---------------------------------------------------------------------------
  148. sub service
  149. {
  150.     my ( $self ) = @_;
  151.  
  152.     $self->calculate_today__();
  153.  
  154.     # We send out a TICKD message every hour so that other modules
  155.     # can do clean up tasks that need to be done regularly but not
  156.     # often
  157.  
  158.     if ( time > ( $self->{last_tickd__} + 3600 ) ) {
  159.         $self->mq_post_( 'TICKD' );
  160.         $self->{last_tickd__} = time;
  161.     }
  162.  
  163.     return 1;
  164. }
  165.  
  166. # ---------------------------------------------------------------------------
  167. #
  168. # calculate_today
  169. #
  170. # Set the global $self->{today} variable to the current day in seconds
  171. #
  172. # ---------------------------------------------------------------------------
  173. sub calculate_today__
  174. {
  175.     my ( $self ) = @_;
  176.  
  177.     # Create the name of the debug file for the debug() function
  178.     $self->{today__} = int( time / $seconds_per_day ) * $seconds_per_day;
  179.  
  180.     # Note that 0 parameter than allows the logdir to be outside the user
  181.     # sandbox
  182.  
  183.     $self->{debug_filename__} = $self->get_user_path_(
  184.         $self->config_( 'logdir' ) . "popfile$self->{today__}.log", 0 );
  185. }
  186.  
  187. # ---------------------------------------------------------------------------
  188. #
  189. # remove_debug_files
  190. #
  191. # Removes popfile log files that are older than 3 days
  192. #
  193. # ---------------------------------------------------------------------------
  194. sub remove_debug_files
  195. {
  196.     my ( $self ) = @_;
  197.  
  198.     my @debug_files = glob( $self->get_user_path_(
  199.                           $self->config_( 'logdir' ) . 'popfile*.log', 0 ) );
  200.  
  201.     foreach my $debug_file (@debug_files) {
  202.         # Extract the epoch information from the popfile log file name
  203.         if ( $debug_file =~ /popfile([0-9]+)\.log/ )  {
  204.             # If older than now - 3 days then delete
  205.             unlink($debug_file) if ( $1 < (time - 3 * $seconds_per_day) );
  206.         }
  207.     }
  208. }
  209.  
  210. # ----------------------------------------------------------------------------
  211. #
  212. # debug
  213. #
  214. # $level      The level of this message
  215. # $message    A string containing a debug message that may or may not be 
  216. #             printed
  217. #
  218. # Prints the passed string if the global $debug is true
  219. #
  220. # ----------------------------------------------------------------------------
  221. sub debug
  222. {
  223.     my ( $self, $level, $message ) = @_;
  224.  
  225.     if ( $self->{initialize_called__} == 0 ) {
  226.         return;
  227.     }
  228.  
  229.     if ( $level > $self->config_( 'level' ) ) {
  230.         return;
  231.     }
  232.  
  233.     if ( $self->{debug_filename__} eq '' ) {
  234.         return;
  235.     }
  236.  
  237.     if ( $self->global_config_( 'debug' ) > 0 ) {
  238.  
  239.         # Check to see if we are handling the USER/PASS command and if
  240.         # we are then obscure the account information
  241.  
  242.         if ( $message =~ /((--)?)(USER|PASS)\s+\S*(\1)/i ) {
  243.             $message = "$`$1$3 XXXXXX$4";
  244.         }
  245.  
  246.         $message =~ s/([\x00-\x1f])/sprintf("[%2.2x]", ord($1))/eg;
  247.  
  248.         my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
  249.             localtime;
  250.         $year += 1900;
  251.         $mon  += 1;
  252.  
  253.         $min  = "0$min"  if ( $min  < 10 );
  254.         $hour = "0$hour" if ( $hour < 10 );
  255.         $sec  = "0$sec"  if ( $sec  < 10 );
  256.  
  257.         my $delim = ' ';
  258.         $delim = "\t" if ( $self->config_( 'format' ) eq 'tabbed' );
  259.         $delim = ',' if ( $self->config_( 'format' ) eq 'csv' );
  260.  
  261.         my $msg =
  262.             "$year/$mon/$mday$delim$hour:$min:$sec$delim$$:$delim$message\n";
  263.  
  264.         if ( $self->global_config_( 'debug' ) & 1 )  {
  265.               if ( open DEBUG, ">>$self->{debug_filename__}" ) {
  266.                 print DEBUG $msg;
  267.                 close DEBUG;
  268.             }
  269.         }
  270.  
  271.         print $msg if ( $self->global_config_( 'debug' ) & 2 );
  272.  
  273.         # Add the line to the in memory collection of the last ten
  274.         # logger entries and then remove the first one if we now have
  275.         # more than 10
  276.  
  277.         push @{$self->{last_ten__}}, ($msg);
  278.  
  279.         if ( $#{$self->{last_ten__}} > 9 ) {
  280.             shift @{$self->{last_ten__}};
  281.         }
  282.     }
  283. }
  284.  
  285. # GETTERS/SETTERS
  286.  
  287. sub debug_filename
  288. {
  289.     my ( $self ) = @_;
  290.  
  291.     return $self->{debug_filename__};
  292. }
  293.  
  294. sub last_ten
  295. {
  296.     my ( $self ) = @_;
  297.  
  298.     if ( $#{$self->{last_ten__}} >= 0 ) {
  299.         return @{$self->{last_ten__}};
  300.     } else {
  301.         my @temp = ( 'log empty' );
  302.         return @temp;
  303.     }
  304. }
  305.  
  306. 1;
  307.